package com.baide.sanguanheyi.swing;

import com.baide.sanguanheyi.config.ThreadManager;
import com.baide.sanguanheyi.interfaces.*;
import com.baide.sanguanheyi.luodao.LService;
import com.baide.sanguanheyi.sqlite.Content;
import com.baide.sanguanheyi.sqlite.ContentService;
import com.baide.sanguanheyi.weight.WeightConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

@Component
public class MainContent extends JPanel implements CtCallBack, WeightCallBack, PlcCallBack, KeyListener {

    @Autowired
    LService lService;
    @Autowired
    String2Voice play;
    CtSendMsg ctSendMsg;
    PlcSendMsg plcSendMsg;
    @Autowired
    WeightConfig weightConfig;
    @Autowired
    ContentService sqliteTools;
    String status = "未启动";//设备默认未启动
    List<Content> saveContents = new ArrayList<>();//暂存用于上包站
    List<Content> contents = new ArrayList<>();//队列
    List<Content> endContents = new ArrayList<>();//移栽队列
    final String lockSqlite = "locakSqlite";
    private Logger logger = LoggerFactory.getLogger(MainContent.class);

    public void setCtSendMsg(CtSendMsg ctSendMsg) {
        this.ctSendMsg = ctSendMsg;
    }

    public void setPlcSendMsg(PlcSendMsg plcSendMsg) {
        this.plcSendMsg = plcSendMsg;
    }

    public MainContent() {
        super(new BorderLayout());
//        ArrayList<Content> c = new ArrayList<>();
//        contents = Collections.synchronizedList(c);
//        ArrayList<Content> j = new ArrayList<>();
//        saveContents = Collections.synchronizedList(j);
//        ArrayList<Content> k = new ArrayList<>();
//        endContents = Collections.synchronizedList(k);
        initContent();
    }

    private void initContent() {
        add(getNorth(), BorderLayout.NORTH);
        add(getCenter(), BorderLayout.CENTER);
        add(getSouth(), BorderLayout.SOUTH);
        setVisible(true);
    }

    JLabel fx, cy, bk;//bg
    AtomicInteger iFx = new AtomicInteger(0);
    AtomicInteger iCy = new AtomicInteger(0);
    AtomicInteger iBk = new AtomicInteger(0);
    AtomicInteger iBg = new AtomicInteger(0);

    private JPanel getSouth() {
        JPanel jPanel = new JPanel();
        JLabel jLabel = new JLabel("放行:");
        jLabel.setFont(new Font("楷体", Font.TYPE1_FONT, 50));
        fx = new JLabel("0");
        fx.setFont(new Font("楷体", Font.TYPE1_FONT, 50));
        fx.setForeground(Color.RED);
        jPanel.add(jLabel);
        jPanel.add(fx);
        JLabel jLabel1 = new JLabel("    查验:  ");
        jLabel1.setFont(new Font("楷体", Font.TYPE1_FONT, 50));
        cy = new JLabel("0");
        cy.setFont(new Font("楷体", Font.TYPE1_FONT, 50));
        cy.setForeground(Color.RED);
        jPanel.add(jLabel1);
        jPanel.add(cy);
        JLabel jLabel2 = new JLabel("    标快:  ");
        jLabel2.setFont(new Font("楷体", Font.TYPE1_FONT, 50));
        bk = new JLabel("0");
        bk.setFont(new Font("楷体", Font.TYPE1_FONT, 50));
        bk.setForeground(Color.RED);
        jPanel.add(jLabel2);
        jPanel.add(bk);
        return jPanel;
    }

    List<Content> data;
    TableModel tableModel;

    private JPanel getCenter() {
        JPanel table = new JPanel();
        table.setLayout(new BorderLayout());
        data = new ArrayList<>();
        tableModel = new TableModel(data);
        JTable table1 = new JTable(tableModel);
        table1.setFont(new Font("Menu.font", Font.PLAIN, 18));
        table1.getTableHeader().setFont(new Font("Dialog", 0, 18));
        JScrollPane js = new JScrollPane(table1);
        table.add(js);
        return table;
    }

    private JPanel getNorth() {
        JPanel jPanel = new JPanel();
        jPanel.setLayout(new BorderLayout());
        JPanel center = new JPanel();
        center.setLayout(new FlowLayout());
        center.add(getConnectPanel());
        jPanel.add(center);
        jPanel.add(codePanel(), BorderLayout.SOUTH);
        return jPanel;
    }

    JTextField smBarcode;
    boolean isUsePerson = false;//是否人工扫码
    boolean isChayan = false;//是否人工扫码时不用剔除查验件
    boolean isUseTuopan = false;//是否使用托盘
    boolean isCtDuBao = false;//是否使用ct堵包功能
    boolean isFuhe = false;//是否使用ct堵包功能
    boolean isFast = false;//是否使用快速通关的功能

    //扫码枪对应的控件
    private JPanel codePanel() {
        JPanel jPanel = new JPanel();
        JLabel jLabel = new JLabel("扫描申报条码:");
        jLabel.setFont(new Font("楷体", Font.TYPE1_FONT, 20));
        smBarcode = new JTextField();
        smBarcode.setFont(new Font("楷体", Font.TYPE1_FONT, 20));
        smBarcode.setForeground(Color.RED);
        smBarcode.setColumns(20);
        smBarcode.addKeyListener(this);
        jPanel.add(jLabel);
        jPanel.add(smBarcode);
        JButton jButton = new JButton("重扫");
        jButton.setFont(new Font("楷体", Font.TYPE1_FONT, 20));
        jButton.addActionListener(new ActionListener() {//点击重扫后清除数据，并获取焦点
            @Override
            public void actionPerformed(ActionEvent e) {
                setSmBarcode();
            }
        });
        jPanel.add(jButton);
        JCheckBox cb = new JCheckBox("人工扫码");
        cb.setFont(new Font("楷体", Font.TYPE1_FONT, 20));
        cb.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                JCheckBox j = (JCheckBox) e.getItem();
                if (j.isSelected()) {
                    isUsePerson = true;
                    plcSendMsg.line2night(1);
                } else {
                    isUsePerson = false;
                    plcSendMsg.line2night(0);
                }
            }
        });
        jPanel.add(cb);
        JCheckBox cb1 = new JCheckBox("人工查验");
        cb1.setFont(new Font("楷体", Font.TYPE1_FONT, 20));
        cb1.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                JCheckBox j = (JCheckBox) e.getItem();
                isChayan = j.isSelected();
            }
        });
        jPanel.add(cb1);
        JCheckBox jj = new JCheckBox("使用托盘");
        jj.setFont(new Font("楷体", Font.TYPE1_FONT, 20));
        jj.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                JCheckBox j = (JCheckBox) e.getItem();
                isUseTuopan = j.isSelected();
            }
        });
        jPanel.add(jj);
        jPanel.add(new JLabel("                 "));
        JCheckBox gg = new JCheckBox("快速通关");
        gg.setFont(new Font("楷体", Font.TYPE1_FONT, 20));
        gg.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                JCheckBox j = (JCheckBox) e.getItem();
                if (j.isSelected()) {
                    isFast = true;
                    plcSendMsg.sendMsg("*G1#");
                } else {
                    isFast = false;
                    plcSendMsg.sendMsg("*G0#");
                }
            }
        });
        jPanel.add(gg);
        JCheckBox dubao = new JCheckBox("CT堵包");
        dubao.setFont(new Font("楷体", Font.TYPE1_FONT, 20));
        dubao.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                JCheckBox j = (JCheckBox) e.getItem();
                if (j.isSelected()) {
                    isCtDuBao = true;
                } else {
                    isCtDuBao = false;
                }
            }
        });
        jPanel.add(dubao);
        JCheckBox fuhe = new JCheckBox("复核");
        fuhe.setFont(new Font("楷体", Font.TYPE1_FONT, 20));
        fuhe.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                JCheckBox j = (JCheckBox) e.getItem();
                if (j.isSelected()) {
                    isFuhe = true;
                    plcSendMsg.sendMsg("*H1#");
                } else {
                    isFuhe = false;
                    plcSendMsg.sendMsg("*H0#");
                }
            }
        });
        jPanel.add(fuhe);
        return jPanel;
    }

    private void setSmBarcode() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                if (smBarcode != null) {
                    smBarcode.setText("");
                    smBarcode.setEditable(true);
                    smBarcode.requestFocus();
                }
            }
        });
    }


    private JPanel getConnectPanel() {
        JPanel jPanel = new JPanel();
        jPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
        JPanel center = new JPanel();
        TitledBorder titledBorder = BorderFactory.createTitledBorder("连接信息");
        titledBorder.setTitleJustification(TitledBorder.TOP);
        center.setBorder(titledBorder);
        center.setLayout(new GridLayout(2, 3));//设置网格布局
        setConnectLabel(center);
        jPanel.add(center);
        jPanel.add(getButton(), BorderLayout.EAST);
        return jPanel;
    }

    String[] connectStrings = new String[]{"CT通讯:", "OBR通讯:", "PLC通讯:", "称重机:", "扫码枪:", "设备运行:"};
    JLabel[] jLabels = new JLabel[6];
    JPanel[] jPanels = new JPanel[6];

    private void setConnectLabel(JPanel jPanel) {
        for (int i = 0; i < connectStrings.length; i++) {
            JPanel panel = new JPanel();
            JLabel label = new JLabel(connectStrings[i]);
            label.setFont(new Font("楷体", Font.TYPE1_FONT, 20));
            JPanel j = new JPanel();
            j.setPreferredSize(new Dimension(110, 30));
            j.add(label);
            JLabel label1 = new JLabel("未连接");
            label1.setFont(new Font("楷体", Font.TYPE1_FONT, 20));
            jLabels[i] = label1;
            JPanel j1 = new JPanel();
            j1.setPreferredSize(new Dimension(110, 30));
            j1.setBackground(Color.RED);
            if (i == 3 || i == 4) {
                label1.setText("已就绪");
                j1.setBackground(Color.GREEN);
            }
            if (i == 5) {
                label1.setText(status);
            }
            if (i == 1) {
                label1.setText("已就绪");
                j1.setBackground(Color.GREEN);
            }
            j1.add(label1);
            jPanels[i] = j1;
            panel.add(j);
            panel.add(j1);
            jPanel.add(panel);
        }
    }

    private JPanel getButton() {
        JPanel jPanel = new JPanel();
        JPanel j = new JPanel();
        j.setLayout(new GridLayout(1, 2, 5, 0));
        JButton start = new JButton("启动");
        start.setFont(new Font("楷体", Font.TYPE1_FONT, 40));
        start.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                status = "已启动";
                plcSendMsg.line2Stop(1);
                jLabels[5].setText(status);
                jPanels[5].setBackground(Color.GREEN);
            }
        });
        JButton stop = new JButton("停止");
        stop.setFont(new Font("楷体", Font.TYPE1_FONT, 40));
        stop.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                status = "未启动";
                plcSendMsg.line2Stop(0);
                jLabels[5].setText(status);
                jPanels[5].setBackground(Color.RED);
            }
        });
        j.add(start);
        j.add(stop);
        jPanel.add(j);
        return jPanel;
    }

    /**
     * ct 回调开始
     */

    @Override
    public void ctConnectSuccess() {
        changeUI(0, "已连接", Color.GREEN);
    }

    @Override
    public void ctConnectOff() {
        changeUI(0, "未连接", Color.RED);
    }

    private void changeUI(int i, String msg, Color color) {
        //回到主线程更新UI
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                jLabels[i].setText(msg);
                jPanels[i].setBackground(color);
            }
        });
    }

    public static Map<String, Map<String, Object>> ctMap = new HashMap<>();

    @Override
    public void ctResult(Map<String, Object> body) {
        logger.info("-------ct反馈条码----------：\n" + body + "\n");
        String barcode = body.get("Barcode").toString();
        ctMap.put(barcode, body);
    }

    private void insertSqlite(Content content) {
        ThreadManager.getThreadPollProxy().execute(new Runnable() {
            @Override
            public void run() {
                synchronized (lockSqlite) {
                    sqliteTools.save(content);
                }
            }
        });
    }

    private void insertLuoDao(Content content) {
        ThreadManager.getThreadPollProxy().execute(new Runnable() {
            @Override
            public void run() {
                lService.insert(content);
            }
        });
    }

    /**
     * ct 回调结束
     */

    //防止重量误触发
    AtomicLong weightInteger = new AtomicLong(0);

    /**
     * 称重机回调
     *
     * @param result
     */
    @Override
    public void weightResult(String result) {
        if (isFast) return;
        if ((weightInteger.get() != 0 && System.currentTimeMillis() - weightInteger.get() < 600) || Integer.parseInt(result) < 10) {
            logger.info("重量误触发了");
            return;
        }
        weightInteger.set(System.currentTimeMillis());
        if (status.equals("未启动")) {
            plcSendMsg.start2Stop(1);
            ThreadManager.getThreadPollProxy().execute(new Runnable() {
                @Override
                public void run() {
                    play.play("未启动");
                }
            });
            setSmBarcode();
            return;
        }
        String code = smBarcode.getText();
        if (code.isEmpty() && barCode.length() > 0 && smBarcode.isEditable()) {
            code = barCode.toString();
            smBarcode.setText("");
            smBarcode.setText(barCode.toString());
            smBarcode.setEditable(false);
            barCode.delete(0, barCode.length());
        } else {
            barCode.delete(0, barCode.length());
        }
        logger.info("重量:" + result + "条码:" + code);
        if (code.equals("NoRead") || code.length() == 0) {
            setSmBarcode();
            ThreadManager.getThreadPollProxy().execute(new Runnable() {
                @Override
                public void run() {
                    play.play("请重新扫码");
                }
            });
            plcSendMsg.start2Stop(1);
        } else {
            saveAndChangeUI(code, result);
        }
    }

    private void saveAndChangeUI(String barCode, String weight) {
        ThreadManager.getThreadPollProxy().execute(new Runnable() {
            @Override
            public void run() {
                Content content = null;
                for (Content c : saveContents) {
                    if (c.getBarCode().equals(barCode)) {
                        content = c;
                        break;
                    }
                }
                if (content == null) {
                    content = new Content();
                    content.setBarCode(barCode);
                }
                if (isUseTuopan) {
                    double i = Double.parseDouble(weight);
                    content.setWeight((i - weightConfig.getToupanWeight()) + "");
                } else
                    content.setWeight(weight);
                if (content.getLuoDao() == null) {
                    Map<String, String> select = lService.selectByBarcode(barCode);
                    content.setPackNo(select.get("pack_no"));
                    content.setVoyageNo(select.get("voyage_no"));
                    content.setMainGName(select.get("main_g_name"));
                    content.setCustOrder(select.get("cust_order"));
                    content.setSEND_NAME(select.get("SEND_NAME"));
                    content.setSENDER_ADDR(select.get("SENDER_ADDR"));
                    content.setSENDER_TEL(select.get("SENDER_TEL"));
                    content.setOWNER_ADDR(select.get("OWNER_ADDR"));
                    content.setOWNER_NAME(select.get("OWNER_NAME"));
                    content.setOWNER_TEL(select.get("OWNER_TEL"));
                    content.setLuoDao(select);
                    content.setTime(System.currentTimeMillis());
                }
                insertSqlite(content);
                data.add(content);
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        tableModel.fireTableDataChanged();
                    }
                });
            }
        });
    }

    StringBuffer barCode = new StringBuffer();
    List<Content> fuheList = new ArrayList<>();

    @Override
    public void OBR(int i, String code) {
        switch (i) {
            case 2:
                if (!isFuhe) return;
                if (code.equals("NoRead")) {
                    Content c = new Content();
                    c.setBarCode("复核没到扫码");
                    c.setLight3(System.currentTimeMillis());
                    c.setMove(3);
                    fuheList.add(c);
                } else {
                    Content byId = null;
                    synchronized (lockSqlite) {
                        byId = sqliteTools.findById(code);
                    }
                    if (byId != null) {
                        byId.setLight3(System.currentTimeMillis());
                        fuheList.add(byId);
                    } else {
                        Content c = new Content();
                        c.setBarCode("复核数据没查询到数据条码:" + code);
                        c.setMove(3);
                        c.setLight3(System.currentTimeMillis());
                        fuheList.add(c);
                    }
                }
                break;
            case 1:
                barCode.delete(0, barCode.length());
                if (isUsePerson) {
                    return;
                }
                barCode.append(code);
                String sm = smBarcode.getText();
                if (sm.isEmpty()) {
                    if (barCode.toString().equals("NoRead")) {
                        plcSendMsg.start2Stop(1);
                        ThreadManager.getThreadPollProxy().execute(new Runnable() {
                            @Override
                            public void run() {
                                play.play("请重新扫码");
                            }
                        });
                    } else {
                        smBarcode.setText(code);
                        smBarcode.setEditable(false);
                        plcSendMsg.start2Stop(0);
                        startSave(code);
                    }
                } else {
                    barCode.delete(0, barCode.length());
                    ThreadManager.getThreadPollProxy().execute(new Runnable() {
                        @Override
                        public void run() {
                            play.play("请慢一点");
                        }
                    });
                }
                break;
        }
    }

    @Override
    public void OBRConnectSuccess(String msg) {
    }

    @Override
    public void OBRConnectOff(String msg) {
    }

    @Override
    public void PLCConnectSuccess() {
        changeUI(2, "已连接", Color.GREEN);
    }

    @Override
    public void PLCConnectOff() {
        changeUI(2, "未连接", Color.GREEN);
    }

    AtomicLong aLong = new AtomicLong(0);
    AtomicLong aLong2 = new AtomicLong(0);
    AtomicLong aLong3 = new AtomicLong(0);
    AtomicLong aLong4 = new AtomicLong(0);

    private int getFuheMove() {
        if (fuheList.size() == 0) {
            logger.info("复核移栽：队列中无数据，移栽出去.");
            return 2;
        } else {
            Content c = fuheList.get(0);
            logger.info("复核移栽：" + c.toString());
            if (c.getLight3() != 0) {
                if (System.currentTimeMillis() - c.getLight3() > 7300) {//大于则说明队列里面少了一个4.2s
                    logger.info("复核移栽：超过时间范围，清除本次移栽，加载下次移栽指令。");
                    fuheList.remove(0);
                    return getMove();//迭代执行下一次
                } else if (System.currentTimeMillis() - c.getLight2() < 4200 - 2150) {//说明多了一个
                    logger.info("复核移栽：小于时间范围，不清除本次移栽，默认移除-3。");
                    return 3;
                } else {
                    logger.info("复核移栽：正常移栽。" + c.toString());
                    fuheList.remove(0);
                    return c.getYZMove();
                }
            } else {
                logger.info("复核移栽：未获取到光电3的时间，此时默认移栽。");
                fuheList.remove(0);
                return c.getYZMove();
            }
        }
    }

    @Override
    public void light(int i) {
        if (isFast) return;
        switch (i) {
            case 4:
                if (!isFuhe) return;
                if (aLong4.get() != 0 && (System.currentTimeMillis() - aLong4.get() < 100)) {
                    return;
                }
                aLong4.set(System.currentTimeMillis());
                if (getFuheMove() == 1) {
                    plcSendMsg.move(2, 1);
                } else {
                    plcSendMsg.move(2, 2);
                }
                break;
            case 1:
                if (aLong.get() != 0 && (System.currentTimeMillis() - aLong.get() < 1600)) {
                    return;
                }
                aLong.set(System.currentTimeMillis());
                String code = smBarcode.getText();
                setSmBarcode();
                logger.info("发送给CT的条码：   " + code);
                if (!code.isEmpty()) {
                    ctSendMsg.sendBarcode(code);
                    //加入队列
                    addContents(code);
                }
                break;
            case 3:
                if (aLong3.get() != 0 && (System.currentTimeMillis() - aLong3.get() < 100)) {
                    return;
                }
                aLong3.set(System.currentTimeMillis());
                logger.info("移栽：开始移栽了！");
                int move = getMove();
                if (move == 3 && isUsePerson && !isCtDuBao) {
                    plcSendMsg.move(1, 1);
                } else {
                    plcSendMsg.move(1, move);
                }
                logger.info("移栽后队列:" + endContents.toString());
                break;
            case 2:
                if (aLong2.get() != 0 && (System.currentTimeMillis() - aLong2.get() < 100)) {
                    return;
                }
                aLong2.set(System.currentTimeMillis());
                dbCount.getAndDecrement();
                if (beCount.get() > 0) {
                    beCount.getAndDecrement();
                    if (beCount.get() <= 0 && futureAtomicReference.get() != null) {
                        futureAtomicReference.get().cancel(true);
                        futureAtomicReference.set(null);
                        if (lastContent != null && lastContent.getHindContents() != null) {
                            lastContent.setHindContents(null);
                        }
                    }
                }
                if (ycCount.get() > 0)
                    ycCount.getAndDecrement();//移除数量
                logger.info("堵包数量:" + dbCount.get() + "   实际操作数量:" + beCount.get());
                if (dbCount.get() < 0) {
                    dbCount.getAndIncrement();//加一个
                    if (endContent != null && endContent.get() != null && endContent.get().getHindContents() != null && endContent.get().getHindContents().size() > 0) {
                        Content c = endContent.get().getHindContents().get(0);
                        if (lastContent != null && lastContent.getHindContents() != null && lastContent.getHindContents().size() > 0) {
                            lastContent.getHindContents().remove(lastContent.getHindContents().size() - 1);
                        }
                        c.setLight2(System.currentTimeMillis());
                        endContent.get().getHindContents().remove(0);
                        logger.info("光电2：<0" + c.toString());
                        c.setHindContents(endContent.get().getHindContents());
                        endContents.add(c);
                        Content t = new Content();
                        BeanUtils.copyProperties(c, t);
                        lastContent = c;
                        endContent.set(t);
                    } else {
                        logger.info("光电2：突然多出来一个包裹，堵包队列里面没有数据！");
                        Content c = new Content();
                        c.setLight2(System.currentTimeMillis());
                        c.setBarCode("这是多出来的包裹");
                        c.setMove(3);
                        endContents.add(c);
                        lastContent = c;
                        Content t = new Content();
                        BeanUtils.copyProperties(c, t);
                        endContent.set(t);
                    }
                } else {
                    if (contents.size() > 0) {
                        logger.info("加入队列前：" + contents.toString());
                        Content c = contents.get(0);
                        c.setLight2(System.currentTimeMillis());
                        logger.info("光电2：>=0" + c.toString());
                        if (dbCount.get() == 0) {
                            if (futureAtomicReference.get() != null) {//3秒内如果收到了光电信息，停止堵包判断
                                futureAtomicReference.get().cancel(true);
                                futureAtomicReference.set(null);
                                if (lastContent != null && lastContent.getHindContents() != null) {
                                    lastContent.setHindContents(null);
                                }
                            }
                            endContents.add(c);
                            if (ycCount.get() > 0) {
                                List<Content> lll = new ArrayList<>();
                                Content t = new Content();
                                BeanUtils.copyProperties(c, t);
                                if (endContent.get() != null && endContent.get().getHindContents() != null) {
                                    lll.addAll(endContent.get().getHindContents());
                                }
                                lll.add(t);
                                c.setHindContents(lll);
                                logger.info("光电2：前面堵包了，移栽需要加上移除的包裹数据共同判断移除方向" + c.toString());
                            }
                            contents.remove(0);
                        } else {
                            beCount.set(dbCount.get());
                            endContents.add(c);
                            contents.remove(0);
                            List<Content> list = new ArrayList<>();
                            if (ycCount.get() > 0) {//上次堵包还没堵完，你有堵包了
                                logger.info("上次堵包还没堵完，你有堵包了,是否将上次还未处理完的移栽队列加入到这次堵包中。");
                                if (endContent.get() != null && endContent.get().getHindContents() != null) {
                                    list.addAll(endContent.get().getHindContents());
                                }
                            }
                            for (int k = 0; k <= beCount.get(); k++) {
                                if (contents.size() > k + 1) {
                                    Content t = new Content();
                                    BeanUtils.copyProperties(contents.get(k), t);
                                    list.add(t);
                                } else {
                                    break;
                                }
                            }
                            c.setHindContents(list);
                            logger.info("光电2：>0 " + c.toString());
                            checkDubao();
                        }
                        lastContent = c;
                        Content t = new Content();
                        BeanUtils.copyProperties(c, t);
                        endContent.set(t);
                        logger.info("加入队列后：" + contents.toString());
                    } else {
                        logger.info("队列里面没有数据，但触发了光电");
                    }
                }
                break;
        }
    }

    private int getMove() {
        if (endContents.size() == 0) {
            logger.info("移栽：没有移栽数据，说明突然多一个出来。");
            return 3;
        } else {
            Content c = endContents.get(0);
            logger.info("移栽：" + c.toString());
            if (c.getLight2() != 0) {
                if (System.currentTimeMillis() - c.getLight2() > 10300) {//大于则说明队列里面少了一个6.3s
                    logger.info("移栽：超过时间范围，清除本次移栽，加载下次移栽指令。");
                    c.getYZMove();//先设置ctOrder，再插入数据库
                    insertSqlAndRemoveCt(c);
                    endContents.remove(0);
                    return getMove();//迭代执行下一次
                } else if (System.currentTimeMillis() - c.getLight2() < 6300 - 2150) {//说明多了一个
                    logger.info("移栽：小于时间范围，不清除本次移栽，默认移除-3。");
                    return 3;
                } else {
                    logger.info("移栽：正常移栽。" + c.toString());
                    insertSqlAndRemoveCt(c);
                    endContents.remove(0);
                    return c.getYZMove();
                }
            } else {
                logger.info("移栽：未获取到光电2的时间，此时默认移栽。");
                endContents.remove(0);
                insertSqlAndRemoveCt(c);
                return c.getYZMove();
            }
        }
    }

    private void insertSqlAndRemoveCt(Content c) {
        timerService.schedule(new Runnable() {
            @Override
            public void run() {
                ctMap.remove(c.getBarCode());
                if (c.getCtOrder() != null && c.getCt() != null) {
                    insertSqlite(c);
                    insertLuoDao(c);
                }
            }
        }, 20000, TimeUnit.MILLISECONDS);
    }

    private void addContents(String barCode) {
        timerService.schedule(new Runnable() {
            @Override
            public void run() {
                Content c = null;
                for (Content saveContent : saveContents) {
                    if (saveContent.getBarCode().equals(barCode)) {
                        c = saveContent;
                    }
                }
                if (c != null) {
                    logger.info("光电1:获取到数据加入队列" + c.toString());
                    c.setLight2(System.currentTimeMillis());
                    contents.add(c);//加入队列
                    dubao();
                    saveContents.remove(c);
                    insertSqlite(c);
                } else {
                    logger.info("光电1:没获取到队列缓存数据,队列将错误。");
                }
            }
        }, 5000, TimeUnit.MILLISECONDS);
    }

    Content lastContent;
    AtomicReference<Content> endContent = new AtomicReference<>();//最后离开的数据
    AtomicInteger beCount = new AtomicInteger(0);//实际堵包数量，后面加的不算
    AtomicInteger dbCount = new AtomicInteger(0);//堵包存在数量，需要每次都保证为0
    AtomicInteger ycCount = new AtomicInteger(0);//实际堵包数量，后面加的不算
    ScheduledExecutorService timerService = Executors.newScheduledThreadPool(200);

    private void dubao() {
        timerService.schedule(new Runnable() {
            @Override
            public void run() {
                logger.info("加到了:" + dbCount.incrementAndGet());
            }
        }, 16300, TimeUnit.MILLISECONDS);
    }

    AtomicReference<ScheduledFuture<?>> futureAtomicReference = new AtomicReference<>();

    private void checkDubao() {
        if (futureAtomicReference.get() != null) {
            futureAtomicReference.get().cancel(true);
            futureAtomicReference.set(null);
        }
        ScheduledFuture<?> schedule = timerService.schedule(new Runnable() {
            @Override
            public void run() {
                int i = beCount.get();
                logger.info("checkDubao堵包了：开始执行。堵包数量为:" + i + "队列里面数量为：" + contents.size());
                if (i > 0) {
                    ycCount.set(i + 2);//堵包了需要移除的数量,避免移栽错位
                    if (contents.size() >= beCount.get()) {
                        for (; i > 0; i--) {
                            dbCount.getAndDecrement();//一直减到0为止
                            contents.remove(0);
                        }
                    }
                }
                beCount.set(0);
            }
        }, 3000, TimeUnit.MILLISECONDS);
        futureAtomicReference.set(schedule);
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            if (!smBarcode.isEditable()) {
                ThreadManager.getThreadPollProxy().execute(new Runnable() {
                    @Override
                    public void run() {
                        play.play("请慢一点");
                    }
                });
                return;
            }
            String code = smBarcode.getText();
            if (!code.isEmpty() && !code.equals("NoRead")) {
                startSave(code);
                smBarcode.setEditable(false);
                plcSendMsg.start2Stop(0);
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }


    public void startSave(String code) {
        ThreadManager.getThreadPollProxy().execute(new Runnable() {
            @Override
            public void run() {
                Map<String, String> select = lService.selectByBarcode(code);
                if (select == null) {
                    setSmBarcode();//暂无数据的时候直接清空条码
                    if (!isUsePerson) {//如果不是人工扫码停止线体
                        plcSendMsg.start2Stop(1);
                    }
                    play.play("查无数据");
                } else {
                    logger.info("洛道的数据:" + select.toString());
                    ThreadManager.getThreadPollProxy().execute(new Runnable() {
                        @Override
                        public void run() {
                            play.play(getOrderString(select.get("cust_order")));
                        }
                    });
                    if (select.get("cust_order").equals("1") && isUsePerson) {
                        if (isChayan)
                            setSmBarcode();
                    }
                    Content byId = null;
                    synchronized (lockSqlite) {
                        byId = sqliteTools.findById(code);//第一步看Content是否存在
                    }
                    if (byId != null) {//不计数

                    } else if (select.get("cust_order").equals("1")) {//查验
                        cy.setText(iCy.incrementAndGet() + "");
                    } else {
                        fx.setText(iFx.incrementAndGet() + "");
                        if (code.startsWith("11")) {//标快
                            bk.setText(iBk.incrementAndGet() + "");
                        }
                    }
                    if (byId == null) {
                        byId = new Content();
                    }
                    byId.setLuoDao(select);
                    byId.setBarCode(code);
                    byId.setPackNo(select.get("pack_no"));
                    byId.setVoyageNo(select.get("voyage_no"));
                    byId.setMainGName(select.get("main_g_name"));
                    byId.setCustOrder(select.get("cust_order"));
                    byId.setSEND_NAME(select.get("SEND_NAME"));
                    byId.setSENDER_ADDR(select.get("SENDER_ADDR"));
                    byId.setSENDER_TEL(select.get("SENDER_TEL"));
                    byId.setOWNER_ADDR(select.get("OWNER_ADDR"));
                    byId.setOWNER_NAME(select.get("OWNER_NAME"));
                    byId.setOWNER_TEL(select.get("OWNER_TEL"));
                    byId.setTime(System.currentTimeMillis());
                    if (isUsePerson && !select.get("cust_order").equals("0")) {
                        synchronized (lockSqlite) {
                            sqliteTools.save(byId);
                        }
                        data.add(byId);
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                tableModel.fireTableDataChanged();
                            }
                        });
                    } else {
                        saveContents.add(byId);
                    }
                }
            }
        });
    }

    private String getOrderString(String order) {
        switch (order) {
            case "0":
                return "放行";
            case "1"://查验
                return "海关布控";
            case "2":
                return "入库";
            case "3":
                return "放行征税";
            case "4":
                return "退运";
            case "5":
                return "拒识";
            case "6":
                return "退单";
        }
        return "未识别";
    }
}
